今天將介紹 TypeSpec 的基礎型別,接著說明如何將其使用在操作的參數和回傳中。
和 OpenAPI 一樣,TypeSpec 支援許多不同的數值型別,讓開發者可視需求選用。首先是最基本的幾種:
型別 | 說明 |
---|---|
numeric |
所有的數值型別 |
integer |
所有的整數 |
float |
二進位制浮點數 |
decimal |
十進位制小數 |
若想更精細的表示數值型別,則有以下型別可使用:
型別 | 說明 |
---|---|
int64 |
64-bit 整數 |
int32 |
32-bit 整數 |
float32 |
32-bit 浮點數 |
float64 |
64-bit 浮點數 |
完整清單可見官方文件。
TypeSpec 也提供其他基礎型別如下:
型別 | 說明 |
---|---|
boolean |
布林 |
string |
字串 |
null |
無值 |
void |
無回傳 |
TypeSpec 也支援 API 常使用的型別,如時間等如下:
型別 | 說明 |
---|---|
utcDateTime |
UTC 標準日期時間 |
offsetDateTime |
指定時區的日期時間 |
url |
網址格式的字串 |
另有 Array<Element>
及 Record<Element>
兩種型別可使用,Array<Element>
為陣列,角括號中可指定陣列中的項目型別;Record<Element>
為 Key-Value 型別,類似其他語言中的 Map<Key, Value> 或 Dictionary<Key, Value>,在 TypeSpec 中,Key 必定為 string
型別。
TypeSpec 完整的型別請見官方文件。
操作的參數對應到 API 的 Request Parameter,和 OpenAPI 規格中一樣須有名字和型別,並可透過 TypeSpec.Http
提供的 @header
、@query
、@path
及 @body
裝飾器標示參數的擺放位置。延續昨日的範例專案,以取得單一會員 API 為範例,請求參數為 memberId
,其型別為 int64
,範例程式碼如下:
// member/member.tsp
import "@typespec/http";
using TypeSpec.Http;
namespace MemberService.Member;
@get()
@route("members/{memberId}")
op get(@path memberId: int64): {};
當沒有指定回傳狀態碼的時候,TypeSpec 會自動視型別是否為 void
判斷為 200 OK
或 204 No Content
。以昨日的 healthCheck
API 為例,op healthCheck(): {};
時編譯出的 openapi.yaml
回傳為 200
,但若改為 op healthCheck(): void;
時編譯出的回傳則為 204
如下:
import "@typespec/http";
import "@typespec/rest";
import "@typespec/openapi3";
using TypeSpec.Http;
@service({
title: "會員服務",
version: "1.0.0"
})
@server("https://api.example.com/v1", "正式環境")
@server("https://api.staging.example.com/v1", "測試環境")
namespace MemberService;
@get()
@route("_hc")
@summary("確認服務健康狀態")
@doc("""
這個 API 用來確認服務是否正常運作。
這個 API 不需要任何參數,只要回應 204 即表示服務正常。
""")
op healthCheck(): void;
openapi: 3.0.0
info:
title: 會員服務
version: 1.0.0
tags: []
paths:
/_hc:
get:
operationId: healthCheck
summary: 確認服務健康狀態
description: |2-
這個 API 用來確認服務是否正常運作。
這個 API 不需要任何參數,只要回應 204 即表示服務正常。
parameters: []
responses:
'204':
description: 'There is no content to send for this request, but the headers may be useful. '
components: {}
servers:
- url: https://api.staging.example.com/v1
description: 測試環境
variables: {}
- url: https://api.example.com/v1
description: 正式環境
variables: {}
我們可在回傳中指定不具名欄位並透過裝飾器 @statusCode
來指定回傳的狀態碼,範例程式碼如下:
op healthCheck(): { @statusCode _: 204 };
大括號中可列出回傳的其他內容,一樣可透過 @header
、@query
、@path
及 @body
裝飾器標示擺放位置。以上面取得單一會員 API 為例,在大括號中宣告回傳的狀態碼、header 中的請求 ID 及 body 中的會員資料結構欄位,程式碼如下:
import "@typespec/http";
using TypeSpec.Http;
namespace MemberService.Member;
@summary("取得單一會員")
@doc("""
這個 API 用來取得單一會員的資料。
這個 API 需要提供會員 ID,並回應該會員的基本資料。
""")
@get()
@route("members/{memberId}")
op get(@path memberId: int64): {
@statusCode _: 200;
@header `x-request-id`: string;
id: int64;
name: string;
email: string;
phone: string;
birthday?: utcDateTime;
};
其中 header 的名稱由於含有 -
所以使用反引號 `名稱`
夾起,而 birthday
欄位為非必填所以使用 ?
表示。
到這邊完整 TypeSpec 專案程式碼如下:
// main.tsp
import "@typespec/http";
import "@typespec/rest";
import "@typespec/openapi3";
import "./member/member.tsp";
using TypeSpec.Http;
@service({
title: "會員服務",
version: "1.0.0"
})
@server("https://api.example.com/v1", "正式環境")
@server("https://api.staging.example.com/v1", "測試環境")
namespace MemberService;
@get()
@route("_hc")
@summary("確認服務健康狀態")
@doc("""
這個 API 用來確認服務是否正常運作。
這個 API 不需要任何參數,只要回應 204 即表示服務正常。
""")
op healthCheck(): { @statusCode _: 204 };
// member/member.tsp
import "@typespec/http";
using TypeSpec.Http;
namespace MemberService.Member;
@summary("取得單一會員")
@doc("""
這個 API 用來取得單一會員的資料。
這個 API 需要提供會員 ID,並回應該會員的基本資料。
""")
@get()
@route("members/{memberId}")
op get(@path memberId: int64): {
@statusCode _: 200;
@header `x-request-id`: string;
id: int64;
name: string;
email: string;
phone: string;
birthday?: utcDateTime;
};
編譯後可得 openapi.yaml
如下:
openapi: 3.0.0
info:
title: 會員服務
version: 1.0.0
tags: []
paths:
/_hc:
get:
operationId: healthCheck
summary: 確認服務健康狀態
description: |2-
這個 API 用來確認服務是否正常運作。
這個 API 不需要任何參數,只要回應 204 即表示服務正常。
parameters: []
responses:
'204':
description: 'There is no content to send for this request, but the headers may be useful. '
/members/{memberId}:
get:
operationId: Member_get
summary: 取得單一會員
description: |2-
這個 API 用來取得單一會員的資料。
這個 API 需要提供會員 ID,並回應該會員的基本資料。
parameters:
- name: memberId
in: path
required: true
schema:
type: integer
format: int64
responses:
'200':
description: The request has succeeded.
headers:
x-request-id:
required: true
schema:
type: string
content:
application/json:
schema:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
email:
type: string
phone:
type: string
birthday:
type: string
format: date-time
required:
- id
- name
- email
- phone
components: {}
servers:
- url: https://api.staging.example.com/v1
description: 測試環境
variables: {}
- url: https://api.example.com/v1
description: 正式環境
variables: {}
Redoc 預覽畫面如下:
明天將介紹如何在 TypeSpec 中建立可重複使用的模型。